package in.srain.cube.util;

import android.content.Context;
import android.text.TextUtils;

import in.srain.cube.R;
import in.srain.cube.util.time.TimeData;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Days;
import org.joda.time.Hours;
import org.joda.time.Minutes;
import org.joda.time.Seconds;
import org.joda.time.Years;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class TimeUtils {

    private static final String TAG = "TimeUtils";

    public static final long MILLIS_IN_SECOND = 1000L;
    public static final long SECONDS_IN_MINUTES = 60L;
    public static final long MINUTES_IN_HOUR = 60L;
    public static final long HOURS_IN_DAY = 24L;
    public static final long DAYS_IN_YEAR = 365L;
    public static final long MINUTE_MS = MILLIS_IN_SECOND * SECONDS_IN_MINUTES;
    public static final long HOUR_MS = MINUTE_MS * MINUTES_IN_HOUR;
    public static final long DAY_MS = HOUR_MS * HOURS_IN_DAY;
    public static final long YEAR_MS = HOUR_MS * HOURS_IN_DAY * DAYS_IN_YEAR;

    public static String getDate(Date date) {
        return new SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE).format(date);
    }

    public static String getDateCN(Date date) {
        return new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINESE).format(date);
    }

    public static String getDate3(String time) {
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        DateTime dateTime = DateTime.parse(time, formatter);
        return dateTime.toString("MM月dd日", Locale.CHINESE);
    }

    public static String getDateCN(String time) {
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        DateTime dateTime = DateTime.parse(time, formatter);
        return dateTime.toString("yyyy年MM月dd日", Locale.CHINESE);
    }

    public static String getServerTime(long serverTime) {
        long nowServerTime = TimeData.getInstance().getServerTime().getTime();
        if (serverTime <= 0 || serverTime >= nowServerTime) {
            return "";
        }

        DateTime sendTime = new DateTime(serverTime);
        DateTime currentTime = new DateTime(nowServerTime);

        if (sendTime.getYear() < currentTime.getYear()) {
            return sendTime.toString("yyyy年MM月dd日 HH:mm", Locale.CHINESE);
        } else {
            if (currentTime.getDayOfYear() - 7 >= 0 && sendTime.getDayOfYear() <= currentTime.getDayOfYear() - 7) {
                return sendTime.toString("MM月dd日 HH:mm", Locale.CHINESE);
            } else {
                if (sendTime.getDayOfWeek() == currentTime.getDayOfWeek()) {
                    return sendTime.toString("HH:mm", Locale.CHINESE);
                } else {
                    if (sendTime.getDayOfWeek() + 1 == currentTime.getDayOfWeek()) {
                        return "昨天" + sendTime.toString("HH:mm", Locale.CHINESE);
                    } else {
                        int week = sendTime.getDayOfWeek();
                        StringBuilder weekString = new StringBuilder();
                        switch (week) {
                            case 1:
                                weekString.append("周一");
                                break;
                            case 2:
                                weekString.append("周二");
                                break;
                            case 3:
                                weekString.append("周三");
                                break;
                            case 4:
                                weekString.append("周四");
                                break;
                            case 5:
                                weekString.append("周五");
                                break;
                            case 6:
                                weekString.append("周六");
                                break;
                            case 7:
                                weekString.append("周日");
                                break;
                        }
                        return weekString.append(sendTime.toString("HH:mm", Locale.CHINESE)).toString();
                    }
                }
            }
        }
    }

    public static String getSimpleTime(long time) {
        long nowTime = TimeData.getInstance().getServerTime().getTime();
        if (time <= 0 || time >= nowTime) {
            return "";
        }

        DateTime sendTime = new DateTime(time);
        DateTime currentTime = new DateTime(nowTime);

        if (sendTime.getYear() < currentTime.getYear()) {
            return sendTime.toString("yyyy年MM月dd日", Locale.CHINESE);
        } else {
            if (sendTime.getWeekOfWeekyear() < currentTime.getWeekOfWeekyear()) {
                return sendTime.toString("MM月dd日", Locale.CHINESE);
            } else {
                if (sendTime.getDayOfWeek() == currentTime.getDayOfWeek()) {
                    return sendTime.toString("HH:mm", Locale.CHINESE);
                } else {
                    if (sendTime.getDayOfWeek() + 1 == currentTime.getDayOfWeek()) {
                        return "昨天";
                    } else {
                        switch (sendTime.getDayOfWeek()) {
                            case 1:
                                return "周一";
                            case 2:
                                return "周二";
                            case 3:
                                return "周三";
                            case 4:
                                return "周四";
                            case 5:
                                return "周五";
                            case 6:
                                return "周六";
                            case 7:
                                return "周日";
                        }
                        return "";
                    }
                }
            }
        }
    }

    public static boolean isInvalidServerTime(long serverTime) {
        return serverTime <= 0 || serverTime > TimeData.getInstance().getServerTime().getTime();
    }

    public static String getTime2(Long time) {
        Date date = new Date(time);
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINESE).format(date);
    }

    public static String getTime3(Long time) {
        Date date = new Date(time);
        return new SimpleDateFormat("MMdd", Locale.CHINESE).format(date);
    }

    public static String getTime4(Long time) {
        Date date = new Date(time);
        return new SimpleDateFormat("MM月dd日", Locale.CHINESE).format(date);
    }

    public static String getTime5(Long time) {
        Date date = new Date(time);
        return new SimpleDateFormat("yyyy.MM.dd", Locale.CHINESE).format(date);
    }

    public static String formAge(String birthday) {
        if (!TextUtils.isEmpty(birthday) && !birthday.equals("0000-00-00")) {
            return String.valueOf(Years.yearsBetween(DateTimeFormat.forPattern("yyyy-MM-dd").withZoneUTC().parseDateTime(birthday), DateTime.now()).getYears());
        }
        return null;
    }

    public static int getAge(String birthday) {
        if (!TextUtils.isEmpty(birthday) && !birthday.equals("0000-00-00")) {
            return Years.yearsBetween(DateTimeFormat.forPattern("yyyy-MM-dd").withZoneUTC().parseDateTime(birthday), DateTime.now()).getYears();
        }
        return 0;
    }

    public static boolean isBefore(String time) {
        if (TextUtils.isEmpty(time)) {
            return true;
        }

        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZone(DateTimeZone.forID("Asia/Shanghai"));
        DateTime dateTime = DateTime.parse(time, formatter);

        return dateTime.isBeforeNow();
    }

    public static String parseTime(String time) {
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        DateTime dateTime = DateTime.parse(time, formatter);

        int days = Days.daysBetween(DateTime.now(), dateTime).getDays();
        int hours = Hours.hoursBetween(DateTime.now(), dateTime).getHours() % 24;
        int minutes = Minutes.minutesBetween(DateTime.now(), dateTime).getMinutes() % 60;
        int seconds = Seconds.secondsBetween(dateTime, DateTime.now()).getSeconds() % 60;

        String t = "";
        if (days > 0) {
            t = t + days + "天";
        }
        if (hours > 0) {
            t = t + hours + "小时";
        }
        if (minutes > 0) {
            t = t + minutes + "分钟";
        }
        if (days == 0 && hours == 0 && minutes == 0) {
            t = t + seconds + "秒";
        }
        return t;
    }

    public static boolean isAfterNow(String begin, int duration) {
        if (TextUtils.isEmpty(begin)) {
            return false;
        }
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        DateTime endTime = DateTime.parse(begin, formatter).plusSeconds(duration);
        return endTime.isAfterNow();
    }

    public static String parseTimeFromNow(String begin, int duration) {
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        DateTime startTime = DateTime.now();
        DateTime endTime = DateTime.parse(begin, formatter).plusSeconds(duration);

        int days = Days.daysBetween(startTime, endTime).getDays();
        int hours = Hours.hoursBetween(startTime, endTime).getHours() % 24;
        int minutes = Minutes.minutesBetween(startTime, endTime).getMinutes() % 60;
        int seconds = Seconds.secondsBetween(startTime, endTime).getSeconds() % 60;

        StringBuilder t = new StringBuilder();
        if (days > 0) {
            t.append(days).append("天");
        }
        if (hours > 0) {
            t.append(hours).append("小时");
        }
        if (minutes > 0) {
            t.append(minutes).append("分钟");
        }
        if (days == 0 && hours == 0 && minutes == 0) {
            t.append(seconds).append("秒");
        }
        return t.toString();
    }

    /**
     * 01:00:19
     *
     * @param t
     * @return
     */
    public static String secondsToDigitalText(long t) {
        t = Math.max(t, 0);
        int hours = (int) (t / 3600) % 24;
        int minutes = (int) (t / 60) % 60;
        int seconds = (int) (t % 60);
        return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds);
    }

    /**
     * 00:19
     *
     * @param durationS
     * @return
     */
    public static String secondsToClockText(long durationS) {
        durationS = Math.max(durationS, 0);
        int hours = (int) (durationS / 3600) % 24;
        int minutes = (int) (durationS / 60) % 60;
        int seconds = (int) (durationS % 60);
        if (hours > 0) {
            return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds);
        } else {
            return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
        }
    }

    /**
     * Only keep the leading unit
     *
     * @param t
     * @return
     */
    public static String secondsToShortText(Context context, long t) {
        int days = (int) (t / 86400);
        int hours = (int) (t / 3600) % 24;
        int minutes = (int) (t / 60) % 60;
        int seconds = (int) (t % 60);

        final String blank = " ";

        StringBuilder sb = new StringBuilder();
        if (days > 0) {
            sb.append(days);
            sb.append(blank);
            if (days == 1) {
                sb.append(context.getString(R.string.unit_day));
            } else {
                sb.append(context.getString(R.string.unit_days));
            }
            return sb.toString();
        }
        if (hours > 0) {
            sb.append(hours);
            sb.append(blank);
            if (hours == 1) {
                sb.append(context.getString(R.string.unit_hour));
            } else {
                sb.append(context.getString(R.string.unit_hours));
            }
            return sb.toString();
        }
        if (minutes > 0) {
            sb.append(minutes);
            sb.append(blank);
            if (minutes == 1) {
                sb.append(context.getString(R.string.unit_minute));
            } else {
                sb.append(context.getString(R.string.unit_minutes));
            }
            return sb.toString();
        }

        if (seconds > 0) {
            sb.append(seconds);
            sb.append(blank);
            if (seconds == 1) {
                sb.append(context.getString(R.string.unit_second));
            } else {
                sb.append(context.getString(R.string.unit_seconds));
            }
            return sb.toString();
        }
        return sb.toString();
    }

    /**
     * 1 小时 19 分 10 秒
     * 1 hour 19 minutes 10 seconds
     *
     * @param t
     * @return
     */
    public static String secondsToLongText(Context context, long t) {
        int days = (int) (t / 86400);
        int hours = (int) (t / 3600) % 24;
        int minutes = (int) (t / 60) % 60;
        int seconds = (int) (t % 60);

        final String blank = " ";

        StringBuilder sb = new StringBuilder();
        if (days > 0) {
            sb.append(days);
            sb.append(blank);
            if (days == 1) {
                sb.append(context.getString(R.string.unit_day));
            } else {
                sb.append(context.getString(R.string.unit_days));
            }
            sb.append(blank);
        }
        if (hours > 0) {
            sb.append(hours);
            sb.append(blank);
            if (hours == 1) {
                sb.append(context.getString(R.string.unit_hour));
            } else {
                sb.append(context.getString(R.string.unit_hours));
            }
            sb.append(blank);
        }
        if (minutes > 0) {
            sb.append(minutes);
            sb.append(blank);
            if (minutes == 1) {
                sb.append(context.getString(R.string.unit_minute));
            } else {
                sb.append(context.getString(R.string.unit_minutes));
            }
            sb.append(blank);
        }

        if (seconds > 0) {
            sb.append(seconds);
            sb.append(blank);
            if (seconds == 1) {
                sb.append(context.getString(R.string.unit_second));
            } else {
                sb.append(context.getString(R.string.unit_seconds));
            }
        }
        return sb.toString();
    }

    public static int minutesBetween(Long start) {
        return Minutes.minutesBetween(new DateTime(start), DateTime.now()).getMinutes();
    }

    public static int millisecondsBetween(long start) {
        return (int) (System.currentTimeMillis() - start);
    }

    public static String[] residueTime(String time) {
        if (TextUtils.isEmpty(time) || TextUtils.equals(time, "null")) {
            return null;
        }
        DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZone(DateTimeZone.forID("Asia/Shanghai")).parseDateTime(time);

        if (dateTime.isBeforeNow()) {
            return null;
        }
        int hours = Hours.hoursBetween(DateTime.now(), dateTime).getHours();
        int minutes = Minutes.minutesBetween(DateTime.now(), dateTime).getMinutes() % 60;
        int seconds = Seconds.secondsBetween(DateTime.now(), dateTime).getSeconds() % 60;

        String sHours = hours > 9 ? hours + "" : "0" + hours;
        String sMinutes = minutes > 9 ? minutes + "" : "0" + minutes;
        String sSeconds = seconds > 9 ? seconds + "" : "0" + seconds;

        return new String[]{sHours, sMinutes, sSeconds};
    }

    public static String[] residueTime1(String time) {
        if (TextUtils.isEmpty(time) || TextUtils.equals(time, "null")) {
            return null;
        }
        DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZone(DateTimeZone.forID("Asia/Shanghai")).parseDateTime(time);

        if (dateTime.isAfterNow()) {
            return null;
        }
        int hours = Hours.hoursBetween(dateTime, DateTime.now()).getHours();
        int minutes = Minutes.minutesBetween(dateTime, DateTime.now()).getMinutes() % 60;
        int seconds = Seconds.secondsBetween(dateTime, DateTime.now()).getSeconds() % 60;

        String sHours = hours > 9 ? hours + "" : "0" + hours;
        String sMinutes = minutes > 9 ? minutes + "" : "0" + minutes;
        String sSeconds = seconds > 9 ? seconds + "" : "0" + seconds;

        return new String[]{sHours, sMinutes, sSeconds};
    }

    /**
     * 结束时间到现在时间时段
     *
     * @param time        开始时间
     * @param plusDays    添加几天
     * @param plusHours   添加几小时
     * @param plusMinutes 添加几分钟
     * @param plusSeconds 添加几秒
     */
    public static String getCountDownTime(String time, int plusDays, int plusHours, int plusMinutes, int plusSeconds) {
        if (TextUtils.isEmpty(time) || TextUtils.equals(time, "null")) {
            return null;
        }
        DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZone(DateTimeZone.forID("Asia/Shanghai")).parseDateTime(time);
        dateTime = dateTime.plusDays(plusDays);
        dateTime = dateTime.plusHours(plusHours);
        dateTime = dateTime.plusMinutes(plusMinutes);
        dateTime = dateTime.plusSeconds(plusSeconds);

        if (dateTime.isBeforeNow()) {
            return null;
        }

        int hours = Hours.hoursBetween(DateTime.now(), dateTime).getHours();
        int minutes = Minutes.minutesBetween(DateTime.now(), dateTime).getMinutes() % 60;
        int seconds = Seconds.secondsBetween(DateTime.now(), dateTime).getSeconds() % 60;

        String sHours = hours > 9 ? hours + "" : "0" + hours;
        String sMinutes = minutes > 9 ? minutes + "" : "0" + minutes;
        String sSeconds = seconds > 9 ? seconds + "" : "0" + seconds;

        return sHours + ":" + sMinutes + ":" + sSeconds;
    }

    public static String[] getCountDownTime1(String time, int plusDays) {
        if (TextUtils.isEmpty(time) || TextUtils.equals(time, "null")) {
            return null;
        }
        DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZone(DateTimeZone.forID("Asia/Shanghai")).parseDateTime(time);
        dateTime = dateTime.plusDays(plusDays);
        if (dateTime.isBeforeNow()) {
            return null;
        }

        int hours = Hours.hoursBetween(DateTime.now(), dateTime).getHours();
        int minutes = Minutes.minutesBetween(DateTime.now(), dateTime).getMinutes() % 60;
        int seconds = Seconds.secondsBetween(DateTime.now(), dateTime).getSeconds() % 60;

        String sHours = hours > 9 ? hours + "" : "0" + hours;
        String sMinutes = minutes > 9 ? minutes + "" : "0" + minutes;
        String sSeconds = seconds > 9 ? seconds + "" : "0" + seconds;

        return new String[]{sHours, sMinutes, sSeconds};
    }

    public static String formTime(String startTime) {
        if (TextUtils.isEmpty(startTime)) {
            return "";
        }
        String[] times = residueTime(startTime);
        if (times == null || times.length != 3 || !StringUtil.isNumber(times[0]) || !StringUtil.isNumber(times[1]) || !StringUtil.isNumber(times[2])) {
            return "";
        }

        int hours = Integer.valueOf(times[0]);
        int minutes = Integer.valueOf(times[1]);
        int seconds = Integer.valueOf(times[2]);

        if (hours == 0 && minutes == 0) {
            return seconds + "秒";
        } else if (hours == 0) {
            return minutes + "分";
        }

        int iTime = hours * 60 * 60 + minutes * 60 + seconds;
        iTime = iTime / 2;
        hours = iTime / 60 / 60;
        minutes = (iTime - hours * 60 * 60) / 60;

        if (hours == 0 && minutes == 0) {
            return seconds + "秒";
        } else if (hours == 0) {
            return minutes + "分";
        }

        return hours + "小时" + minutes + "分";
    }

    public static String formTime1(String time) {
        if (TextUtils.isEmpty(time) || !StringUtil.isNumber(time)) {
            return "";
        }

        int seconds = Integer.valueOf(time);
        int hours = seconds / 60 / 60;
        int minutes = (seconds - hours * 60 * 60) / 60;

        if (hours == 0 && minutes == 0) {
            return seconds + "秒";
        } else if (hours == 0) {
            return minutes + "分";
        }

        return hours + "小时" + minutes + "分";
    }

    public static boolean isSameDay(Calendar calendar1, Calendar calendar2) {
        if (calendar1 != null && calendar2 != null) {
            return calendar1.get(Calendar.ERA) == calendar2.get(Calendar.ERA)
                    && calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
                    && calendar1.get(Calendar.DAY_OF_YEAR) == calendar2.get(Calendar.DAY_OF_YEAR);
        } else {
            return false;
        }
    }
}
